package com.uci.scheduleshare;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.uci.scheduleshare.calendar.Contact;

/*SurfaceView for drawing the calendar grid as well as the event objects*/
public class CalendarView extends SurfaceView implements SurfaceHolder.Callback {
	private DrawThread dt; //thread for drawing onto CalendarView
	private List<Contact> contacts; //list of contacts for finding events to draw onto the CalendarView
	private int minutesInDay = 1440; //number of minutes in a day for calculating how big event rectangles are drawn to be
	private final int calendarViewBackground = 0xFFdcdcdc;
	private final int lineColor = 0xFFb2b2b2;
	
	//initialize Calendarview
	public CalendarView(Context context, List<Contact> contacts){
		super(context);
		getHolder().addCallback(this);
		this.contacts = contacts;
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		
	}
	
	//Start the DrawThread when the surface is created
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		dt = new DrawThread(getHolder(), this);
		dt.start();
		dt.setRunning(true);
	}

	//When the surface is destroyed, end the draw thread
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		boolean retry = true;
		if (dt != null){
			dt.setRunning(false);
			while (retry){
				try{
					dt.join();
					retry = false;
				}catch(InterruptedException e){
					
				}
			}
		}
	}
	
	@Override
	public void onDraw(Canvas canvas){
		if (canvas != null){
			//canvas.drawColor(Color.BLACK); //initialize a black canvas
			canvas.drawColor(calendarViewBackground);
			int dayLength = getWidth()/7; //calculate how far apart column lines should be
			Paint calendarLines = new Paint(); //initialize paint used to draw the calendar's grid
			calendarLines.setColor(lineColor); //set paint color to white
			
			//draw the column lines for the calender's grid
			for (int i=1; i<8; i++){
				canvas.drawLine(getWidth()/7*i, 0, getWidth()/7*i, getHeight(), calendarLines);
			}
			//draw the row lines for the calendar's grid
			for (int i=1; i <24; i++){
				canvas.drawLine(0, getHeight()/24*i, getHeight(), getHeight()/24*i, calendarLines);
			}
			
			Paint p = new Paint(); //new paint to be used for drawing event objects
			
			//if there is more than 1 contact
			if (contacts.size() > 0){
				//for each contact
				for (int i=0; i < contacts.size(); i++){
					//if the contact has been selected to be shown
					if (contacts.get(i).isChecked()){
						//retrieve each event for that contact and draw it
						for (int j=0; j < contacts.get(i).getEvents().size(); j++){
							//calculate the parameters for drawing the event rectangle
							//if the event takes place all in 1 day, draw a single rectangle
							if (contacts.get(i).getEvents().get(j).getStartDay() == contacts.get(i).getEvents().get(j).getEndDay()){
								/*Check to make sure that the event is not actually a week long event starting and ending on the same day*/
								if (contacts.get(i).getEvents().get(j).getStartMin() < contacts.get(i).getEvents().get(j).getEndMin()){
									int dayLeft = (contacts.get(i).getEvents().get(j).getStartDay()-1)*dayLength;
									int dayRight = (contacts.get(i).getEvents().get(j).getEndDay())*dayLength;
									float dayTop = contacts.get(i).getEvents().get(j).getStartMin();
									dayTop = dayTop/minutesInDay * getHeight();
									float dayBot = contacts.get(i).getEvents().get(j).getEndMin();
									dayBot = dayBot/minutesInDay * getHeight();
									//get the color that has been selected for the contact
									p.setColor(contacts.get(i).getColor());
									//draw rectangle
									canvas.drawRect(dayLeft, dayTop, dayRight, dayBot, p);
								}
								else{
									/*do nothing because CalendarView currently only supports the current week*/
								}
							}else{
								/*Otherwise, the event spans multiple days so first draw a rectangle to fill in the remaining
								 * time on the first day*/
								int dayLeft = (contacts.get(i).getEvents().get(j).getStartDay()-1)*dayLength;
								int dayRight = contacts.get(i).getEvents().get(j).getStartDay()*dayLength;
								float dayTop = contacts.get(i).getEvents().get(j).getStartMin();
								dayTop = dayTop/minutesInDay * getHeight();
								float dayBot = getHeight();
								p.setColor(contacts.get(i).getColor());
								canvas.drawRect(dayLeft, dayTop, dayRight, dayBot, p);
								/*Then completely fill in the days between the start day and the end day*/
								
								int tmpLength = contacts.get(i).getEvents().get(j).getEndDay() 
												- contacts.get(i).getEvents().get(j).getStartDay() - 1;
								dayTop = 0; //for all remaining rectangles, the rectangle will begin at the top of the canvas
								if (tmpLength > 0){
									/*If tmpLength is >0, then the current event starts and ends in the same week
									 * and there is at least 1 day between the start and end day*/
									dayLeft = contacts.get(i).getEvents().get(j).getStartDay()*dayLength;
									dayRight = (contacts.get(i).getEvents().get(j).getEndDay()-1)*dayLength;
									canvas.drawRect(dayLeft, dayTop, dayRight, dayBot, p);
									
								}else if (tmpLength < 0){
									/*If tmpLength is <0, the event continues into the next week so 
									 * just fill in the rest of the week*/
									dayLeft = contacts.get(i).getEvents().get(j).getStartDay()*dayLength;
									dayRight = getWidth();
									canvas.drawRect(dayLeft, dayTop, dayRight, dayBot, p);
								}
								/*If tmpLength is >=0, then the current event starts and ends in the current
								 * week, so draw the rectangle that represents the last day*/
								if (tmpLength >= 0){
									dayLeft = (contacts.get(i).getEvents().get(j).getEndDay()-1)*dayLength;
									dayRight = contacts.get(i).getEvents().get(j).getEndDay()*dayLength;
									dayBot = contacts.get(i).getEvents().get(j).getEndMin();
									dayBot = dayBot/minutesInDay * getHeight();
									canvas.drawRect(dayLeft, dayTop, dayRight, dayBot, p);
								}
								
							}
						}
					}	
				}
			}
		}
	}
}


//DrawThread for drawing on the CalendarView
class DrawThread extends Thread{
	private SurfaceHolder sh;
	private CalendarView cv;
	private boolean run = false;
	
	public DrawThread(SurfaceHolder surfaceHolder, CalendarView calendarView){
		sh = surfaceHolder;
		cv = calendarView;
	}
	
	public void setRunning(boolean run){
		this.run = run;
	}
	
	/*While thread is running, try to draw on the canvas*/
	@Override
	public void run(){
		Canvas c;
		while (run){
			c = null;
			try{
				c = sh.lockCanvas(null);
				synchronized (sh) {
					cv.onDraw(c);
				}
			}finally{
				if (c != null){
					sh.unlockCanvasAndPost(c);
				}
			}
		}
	}
}
